package com.authine.cloudpivot.ext.utils;

import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.authine.hermes.app.launcher.cmd.CmdWrapper;
import com.authine.hermes.app.launcher.service.BOService;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.cmd.BatchDeleteBOCmd;
import com.authine.mvp.app.launcher.dto.bo.cmd.CreateBOCmd;
import com.authine.mvp.app.launcher.dto.bo.cmd.DeleteBOCmd;
import com.authine.mvp.app.launcher.dto.bo.cmd.UpdateBOCmd;
import com.authine.mvp.app.launcher.dto.bo.query.ListBOQuery;
import com.authine.mvp.app.launcher.dto.bo.query.LoadBOQuery;
import com.authine.mvp.app.launcher.dto.bo.query.expression.*;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @ClassName BoServiceUtils
 * @Description: 封装boServices的增删改查
 * @Author fj
 * @Date 2021/4/9
 * @Version V1.0
 **/
@Slf4j
public class BoServiceUtils {
    private static final CmdWrapper wrapper = new CmdWrapper();

    public static final String ACTION_NAME_CREATE_BO = "createBO";
    public static final String ACTION_NAME_UPDATE_BO = "updateBO";
    public static final String ACTION_NAME_DELETE_BO = "deleteBO";
    public static final String ACTION_NAME_BATCH_DELETE_BO = "batchDeleteBO";

    public static final BOService boService = ApplicationContextUtils.getBean(BOService.class);


    /**
     * 查询单条数据
     *
     * @param bizObjectId
     * @param permission
     * @param schemaCode
     * @param isOnlyLoadOneself
     * @return
     */
    public static SingleResponse<BO> loadBo(String bizObjectId, boolean permission, String schemaCode, boolean isOnlyLoadOneself) {
        LoadBOQuery loadBOQuery = new LoadBOQuery();
        loadBOQuery.setBizObjectId(bizObjectId);
        loadBOQuery.setPermission(permission);
        loadBOQuery.setSchemaCode(schemaCode);
        loadBOQuery.setOnlyLoadOneself(isOnlyLoadOneself);
        return boService.load(loadBOQuery);
    }

    public static SingleResponse<BO> loadBo(String bizObjectId, String schemaCode) {

        return loadBo(bizObjectId, false, schemaCode, false);
    }

    /**
     * 单个条件的简单查询
     *
     * @param schemaCode
     * @param columnName
     * @param columnValue
     * @return
     */
    public static SingleResponse<BOList> findListBySimple(String schemaCode, String columnName, Object columnValue) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        SimpleCondition condition = new SimpleCondition(columnName, Operator.EQ, columnValue);
        listQry.setCondition(condition);
        return boService.list(listQry);
    }

    public static SingleResponse<BOList> findListByCondition( String schemaCode, Condition condition) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        listQry.setCondition(condition);
        SingleResponse<BOList> list = boService.list(listQry);
        log.info("BoServiceUtils findListBySimple list:{}" , list);
        if(!list.isSuccess()){
            throw BoUtils.bizException("模型列表查询出错："+schemaCode+":"+list.getErrMessage());
        }
        return list;
    }

    public static SingleResponse<BOList> findListByConditionByPage( String schemaCode, Condition condition,int pageIndex,int pageSize) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(pageIndex);
        listQry.setPageSize(pageSize);
        listQry.setSchemaCode(schemaCode);
        listQry.setCondition(condition);
        SingleResponse<BOList> list = boService.list(listQry);
        log.info("BoServiceUtils findListBySimple list:{}" , list);
        if(!list.isSuccess()){
            throw BoUtils.bizException("模型列表查询出错："+schemaCode+":"+list.getErrMessage());
        }
        return list;
    }

    /**
     * @param schemaCode
     * @param columnName
     * @param columnValue
     * @return
     */
    public static SingleResponse<BOList> findListByIn(String schemaCode, String columnName, Object columnValue) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        SimpleCondition condition = new SimpleCondition(columnName, Operator.IN, columnValue);
        listQry.setCondition(condition);
        return boService.list(listQry);
    }

    /**
     * 单个条件的简单查询
     *
     * @param schemaCode
     * @param columnName
     * @param columnValue
     * @return
     */
    public static SingleResponse<BOList> findListByLike(String schemaCode, String columnName, Object columnValue) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        SimpleCondition condition = new SimpleCondition(columnName, Operator.LIKE, columnValue);
        listQry.setCondition(condition);
        return boService.list(listQry);
    }

    /**
     * 多个条件的复杂查询
     *
     * @param schemaCode
     * @param columnNames
     * @param columnValues
     * @param operators
     * @return
     */
    public static SingleResponse<BOList> findListByComplex(String schemaCode, String[] columnNames, Object[] columnValues, Operator[] operators) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        ComplexCondition complexCondition = new ComplexCondition();
        complexCondition.setNature(Nature.AND);
        for (int i = 0; i < columnNames.length; i++) {
            SimpleCondition condition = new SimpleCondition(columnNames[i], operators[i], columnValues[i]);
            complexCondition.getConditions().add(condition);
        }
        listQry.setCondition(complexCondition);
        return boService.list(listQry);
    }

    /**
     * 多个条件的or查询,带分页
     *
     * @param schemaCode
     * @param columnNames
     * @param columnValues
     * @param operators
     * @return
     */
    public static SingleResponse<BOList> findListByOrAndLimit(String schemaCode, String[] columnNames, Object[] columnValues, Operator[] operators, int pageIndex, int pageSize) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(pageIndex);
        listQry.setPageSize(pageSize);
        listQry.setSchemaCode(schemaCode);
        ComplexCondition complexCondition = new ComplexCondition();
        complexCondition.setNature(Nature.OR);
        for (int i = 0; i < columnValues.length; i++) {
            SimpleCondition condition = new SimpleCondition(columnNames[i], operators[i], columnValues[i]);
            complexCondition.getConditions().add(condition);
        }
        listQry.setCondition(complexCondition);
        return boService.list(listQry);
    }

    /**
     * 多个条件的and查询,带分页
     *
     * @param schemaCode
     * @param columnNames
     * @param columnValues
     * @param operators
     * @return
     */
    public static SingleResponse<BOList> findListAndLimit(String schemaCode, String[] columnNames, Object[] columnValues, Operator[] operators, int pageIndex, int pageSize) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(pageIndex);
        listQry.setPageSize(pageSize);
        listQry.setSchemaCode(schemaCode);
        ComplexCondition complexCondition = new ComplexCondition();
        complexCondition.setNature(Nature.AND);
        for (int i = 0; i < columnValues.length; i++) {
            SimpleCondition condition = new SimpleCondition(columnNames[i], operators[i], columnValues[i]);
            complexCondition.getConditions().add(condition);
        }
        listQry.setCondition(complexCondition);
        return boService.list(listQry);
    }

    /**
     * 插入数据
     *
     * @param schemaCode
     * @param data
     * @return
     */
    public static SingleResponse<BO> createBo(String schemaCode, List<Map<String, Object>> data) {
        CreateBOCmd createBOCmd = new CreateBOCmd();
        createBOCmd.setSchemaCode(schemaCode);
        createBOCmd.setData(data);
        createBOCmd.setActionName(ACTION_NAME_CREATE_BO);
        wrapper.setSubmitCmd(createBOCmd);
        return boService.create(createBOCmd);
    }

    /**
     * 更新主表数据
     *
     * @param schemaCode
     * @param data
     * @return
     */
    public static SingleResponse<BO> updateMainBo(String schemaCode, List<Map<String, Object>> data) {
        UpdateBOCmd updateBOCmd = new UpdateBOCmd();
        updateBOCmd.setSchemaCode(schemaCode);
        updateBOCmd.setData(data);
        updateBOCmd.setActionName(ACTION_NAME_UPDATE_BO);

        return boService.update(updateBOCmd);
    }


    public static SingleResponse<BO> updateMainBo(String schemaCode, Map<String, Object> data) {

        return updateMainBo(schemaCode, Collections.singletonList(data));
    }

    /**
     * 更新子表数据
     *
     * @param schemaCode
     * @param data
     * @return
     */
    public static SingleResponse<BO> updateChildBo(String schemaCode, String foreignKeyCode, List<Map<String, Object>> data) {
        UpdateBOCmd updateChildBOCmd = new UpdateBOCmd();
        updateChildBOCmd.setMain(false);
        updateChildBOCmd.setSchemaCode(schemaCode);
        updateChildBOCmd.setData(data);
        updateChildBOCmd.setForeignKeyCode(foreignKeyCode);
        updateChildBOCmd.setActionName(ACTION_NAME_UPDATE_BO);
        wrapper.setSubmitCmd(updateChildBOCmd);

        return boService.update(updateChildBOCmd);
    }

    /**
     * 删除单条数据
     *
     * @param schemaCode
     * @param bizObjectId
     * @param onlyDeleteOneself
     * @return
     */
    public static Response deleteBo(String schemaCode, String bizObjectId, boolean onlyDeleteOneself) {
        DeleteBOCmd deleteBOCmd = new DeleteBOCmd();
        deleteBOCmd.setSchemaCode(schemaCode);
        deleteBOCmd.setBizObjectId(bizObjectId);
        deleteBOCmd.setOnlyDeleteOneself(onlyDeleteOneself);
        deleteBOCmd.setActionName(ACTION_NAME_DELETE_BO);
        wrapper.setSubmitCmd(deleteBOCmd);

        return boService.delete(deleteBOCmd);
    }

    public static SingleResponse<BOList> findListBySimple(String schemaCode, String columnName, Object columnValue, Operator operator) {
        ListBOQuery listQry = new ListBOQuery();
        listQry.setPageIndex(-1);
        listQry.setSchemaCode(schemaCode);
        SimpleCondition condition = new SimpleCondition(columnName, operator, columnValue);
        listQry.setCondition(condition);
        SingleResponse<BOList> list = boService.list(listQry);
        log.info("BoServiceUtils findListBySimple list:{}" , list);
        if(!list.isSuccess()){
            throw BoUtils.bizException("模型列表查询出错："+schemaCode+":"+list.getErrMessage());
        }
        return list;
    }

    /**
     * 批量删除数据
     *
     * @param schemaCode
     * @param bizObjectIds
     * @param onlyDeleteOneself
     * @return
     */
    public static Response batchDeleteBO(String schemaCode, List<String> bizObjectIds, boolean onlyDeleteOneself) {
        BatchDeleteBOCmd batchDeleteBOCmd = new BatchDeleteBOCmd();
        batchDeleteBOCmd.setSchemaCode(schemaCode);
        batchDeleteBOCmd.setBizObjectIds(bizObjectIds);
        batchDeleteBOCmd.setOnlyDeleteOneself(onlyDeleteOneself);
        batchDeleteBOCmd.setActionName(ACTION_NAME_BATCH_DELETE_BO);
        wrapper.setSubmitCmd(batchDeleteBOCmd);

        return boService.batchDelete(batchDeleteBOCmd);
    }


}
